//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Query Application Block
//===============================================================================

using System.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder;
using Microsoft.Practices.ObjectBuilder2;
using EntLibContrib.Query.Configuration;

namespace EntLibContrib.Query
{
	/// <summary>
  /// This type supports the Enterprise Library infrastructure and is not intended to be used directly from your code.
	/// Represents the process to build an instance of <see cref="IParameterSet"/> described by a <see cref="ParameterSetData"/> configuration object.
  /// </summary>
	public class ParameterSetCustomFactory : AssemblerBasedCustomFactory<IParameterSet, ParameterSetData>
	{
		#region Public Methods
		/// <summary>
		/// This method supports the Enterprise Library infrastructure and is not intended to be used directly from your code.
		/// Builds an <see cref="IParameterSet"/> described by the <see cref="ParameterSetData"/> configuration object.
		/// </summary>
		/// <param name="context">The <see cref="IBuilderContext"/> that represents the current building process.</param>
		/// <param name="objectConfiguration">The configuration object that describes the object to build.</param>
		/// <param name="configurationSource">The source for configuration objects.</param>
		/// <param name="reflectionCache">The cache to use retrieving reflection information.</param>
		/// <returns>
		/// A fully initialized instance of <see cref="IParameterSet"/>.
		/// </returns>
		public override IParameterSet Create(IBuilderContext context, ParameterSetData objectConfiguration, IConfigurationSource configurationSource, ConfigurationReflectionCache reflectionCache)
		{
			IParameterSet parameterSet = base.Create(context, objectConfiguration, configurationSource, reflectionCache);

			// register the object in the cache
			RegisterObject(context, objectConfiguration.Name, parameterSet);

			return parameterSet;
		}
		#endregion

		#region Protected Methods
		/// <summary>
		/// Returns the configuration object that represents the named <see cref="IParameterSet"/> instance in the specified <paramref name="configurationSource"/>.
		/// </summary>
		/// <param name="name">The name of the required instance.</param>
		/// <param name="configurationSource">The configuration source that has the configuration object.</param>
		/// <returns>
		/// The configuration object that represents the instance with name <paramref name="name"/> in the query
		/// configuration section from <paramref name="configurationSource"/>
		/// </returns>
		/// <exception cref="ConfigurationErrorsException"><paramref name="configurationSource"/> does not contain
		/// query settings, or the <paramref name="name"/> does not exist in the query settings.</exception>
		protected override ParameterSetData GetConfiguration(string name, IConfigurationSource configurationSource)
		{
			QueryConfigurationView view = new QueryConfigurationView(configurationSource);
			return view.GetParameterSetData(name);
		}
		#endregion

		#region Private Methods
		/// <summary>
		/// Registers the object in a managed cache.
		/// </summary>
		/// <param name="context">The context.</param>
		/// <param name="name">The instance name from configuration.</param>
		/// <param name="createdObject">The created object.</param>
		/// <remarks>The ObjectBuilder framework searches the cache before attempting to create new objects
		/// and thus improves performance for objects accessed multiple times</remarks>
		private static void RegisterObject(IBuilderContext context, string name, IParameterSet createdObject)
		{
			if (context.Locator != null)
				context.Locator.Add(new NamedTypeBuildKey(typeof(IParameterSet), name), createdObject);

			if (context.Lifetime != null)
				context.Lifetime.Add(createdObject);
		}
		#endregion
	}
}
